package id.co.shuba.spamobile;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Xml;
import android.widget.TextView;
import android.widget.Toast;
import id.co.shuba.spamobile.data.DatabaseHandler;
import id.co.shuba.spamobile.model.UserInfo;
import id.co.shuba.spamobile.util.Str;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.xmlpull.v1.XmlPullParser;

@SuppressLint("SimpleDateFormat")
public class App {
	public static boolean DEBUG = false;
	public static boolean UAT = true;	

	public static String IV_DES = "@5HU84!5";
	public static String IV = "@5HU84!50lUt10Ns";
	public static String Key = "!@#$Exp3ct0Patr0nusCh4rm";

	public static final int REQUEST_EDIT_PIPELINE = 1;
	public static final int REQUEST_EDIT_PROSPECT = 2;
	public static final int REQUEST_EDIT_DSAR = 3;
	public static final int REQUEST_EDIT_MAINTENANCE_VISIT = 4;
	public static final int REQUEST_VIEW_PROSPECT = 5;

	public static final int SHOW_DATE_PICKER = 6;
	public static final int SHOW_TIME_PICKER = 7;
	public static final int SHOW_CONFIRM = 8;
	public static final int SHOW_LIST = 9;

	public static final int EXPIRED_OFFLINE_DAY = 5;
	public static final float MAX_ROW_UPLOAD = 1000;

	public static final String TIME_ONLY_FORMAT = "HH:mm:ss";
	public static final String TIME_ONLY_FORMAT2 = "HHmmss";
	public static final String TIME_ONLY_FORMAT3 = "HH:mm";
	public static final String DATE_ONLY_FORMAT = "yyyy-MM-dd";
	public static final String DATE_ONLY_FORMAT2 = "yyMMdd";
	public static SimpleDateFormat timeOnly = new SimpleDateFormat(
			TIME_ONLY_FORMAT);
	public static SimpleDateFormat timeOnly2 = new SimpleDateFormat(
			TIME_ONLY_FORMAT2);
	public static SimpleDateFormat dateOnly = new SimpleDateFormat(
			DATE_ONLY_FORMAT);
	public static SimpleDateFormat dateOnly2 = new SimpleDateFormat(
			DATE_ONLY_FORMAT2);
	public static SimpleDateFormat dateTime = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	public static String getAppVersion(Context context) {
		try {
			String versionName = context.getPackageManager()
				    .getPackageInfo(context.getPackageName(), 0).versionName;
			return versionName;
		} catch (NameNotFoundException e) {
			return "n/a";
		}
	}
	
	public static Date processDate = new Date();

	public static Date getMinDate() {
		Calendar c = GregorianCalendar.getInstance();
		c.set(2009, 1, 1, 0, 0, 0);
		return c.getTime();
	}

	public static void reloadDebug(Context ctx) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(ctx);
		DEBUG = prefs.getBoolean("debug", false);
	}

	public static String toTimeString(int hour, int minute) {
		String h = String.valueOf(hour);
		String m = String.valueOf(minute);
		if (h.length() == 1)
			h = "0" + h;
		if (m.length() == 1)
			m = "0" + m;
		return h + ":" + m;
	}

	public static File getOfflineUpdatePath(String fileName) {
		File sdPat = Environment.getExternalStorageDirectory();
		File importPath = new File(sdPat, "spamobile/import");
		return new File(importPath, fileName);
	}

	public static String createCompleteKey(String key) {
		String completeKey = key.replace(key,
				key + App.Key.substring(0, 24 - key.length()));
		return completeKey;
	}

	public static String getProcessDateTime() {
		Date now = new Date();
		String date = dateOnly.format(processDate) + " " + timeOnly.format(now);
		return date;
	}

	public static String getProcessDate() {
		String date = dateOnly.format(processDate);
		return date;
	}

	public static String formatSimpleDate(Date date) {
		return dateOnly.format(date);
	}

	public static String createProspectID(UserInfo user) {
		return createProspectID(user.getUnitCode(), user.getAoCode());
	}

	public static String createProspectID(String branchID, String aoCode) {		
		if (aoCode.length() < 5)
			aoCode = paddingString(aoCode, 5, 'X', false);
		
		String id = branchID + aoCode
				+ dateOnly2.format(processDate) + timeOnly2.format(new Date());
		
		if (id.length() < 21)
			id = paddingString(id, 21, 'X', false);
		
		if (id.length() > 21)
			id = id.substring(0, 21);
		
		return id;
	}

	public static String paddingString(String s, int n, char c,
			boolean paddingLeft) {
		if (s == null) {
			return s;
		}
		int add = n - s.length();
		if (add <= 0) {
			return s;
		}
		StringBuffer str = new StringBuffer(s);
		char[] ch = new char[add];
		Arrays.fill(ch, c);
		if (paddingLeft) {
			str.insert(0, ch);
		} else {
			str.append(ch);
		}
		return str.toString();
	}

	public static String getImei(Context ctx) {
		TelephonyManager telephonyManager = (TelephonyManager) ctx
				.getSystemService(Context.TELEPHONY_SERVICE);
		String imei = telephonyManager.getDeviceId();
		if (Str.isNullOrEmpty(imei))
			imei = "000000000000000";

		return imei;
	}

	public static boolean isNetworkAvailable(Context ctx) {
		ConnectivityManager connectivityManager = (ConnectivityManager) ctx
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo activeNetworkInfo = connectivityManager
				.getActiveNetworkInfo();
		return activeNetworkInfo != null;
	}

	public static String getDefaultValue(Context ctx) {
		return ctx.getString(R.string.default_option);
	}

	public static boolean isDebug(Context ctx) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(ctx);
		return prefs.getBoolean("debug", true);
	}

	public static String getCoordinate(Context ctx) {
		LocationManager lm = (LocationManager) ctx
				.getSystemService(Context.LOCATION_SERVICE);
		List<String> providers = lm.getProviders(true);

		Location l = null;

		for (int i = providers.size() - 1; i >= 0; i--) {
			l = lm.getLastKnownLocation(providers.get(i));
			if (l != null)
				break;
		}
		return String.format("%s, %s", l.getLongitude(), l.getLatitude());

	}

	public static String getBranchID(Context ctx) throws Exception {
		File sdPat = Environment.getExternalStorageDirectory();
		File file = new File(sdPat, "spamobile/br");

		if (!file.exists())
			return null;

		String imei = App.getImei(ctx);

		FileInputStream fis = null;
		CipherInputStream cis = null;

		try {
			fis = new FileInputStream(file);

			SecretKeySpec localSecretKeySpec = new SecretKeySpec(App
					.createCompleteKey(imei).getBytes(), Encryptor.ALGO_AES);

			Cipher localCipher = Cipher.getInstance(Encryptor.ENC_AES);
			IvParameterSpec ivspec = new IvParameterSpec(App.IV.getBytes());
			localCipher.init(Cipher.DECRYPT_MODE, localSecretKeySpec, ivspec);

			cis = new CipherInputStream(fis, localCipher);

			String branchID = read(cis, 64);

			return branchID;
		} catch (Exception e) {
			if (e.getMessage() != null)
				throw e;
		} finally {
			try {
				if (cis != null)
					cis.close();
				if (fis != null)
					fis.close();
			} catch (Exception e2) {
				if (e2.getMessage() != null)
					throw e2;
			}
		}

		return null;
	}

	public static String read(final InputStream is, final int bufferSize) {
		final char[] buffer = new char[bufferSize];
		final StringBuilder out = new StringBuilder();
		try {
			final Reader in = new InputStreamReader(is, "UTF-8");
			try {
				for (;;) {
					int rsz = in.read(buffer, 0, buffer.length);
					if (rsz < 0)
						break;
					out.append(buffer, 0, rsz);
				}
			} finally {
				in.close();
			}
		} catch (UnsupportedEncodingException ex) {
			Log.e("App", ex.getMessage());
		} catch (IOException ex) {
			Log.e("App", ex.getMessage());
		}
		return out.toString();
	}

	public static void setBranchID(Context ctx, String branchID)
			throws Exception {
		File sdPat = Environment.getExternalStorageDirectory();
		File file = new File(sdPat, "spamobile/br");

		if (file.exists())
			file.delete();

		String imei = App.getImei(ctx);

		FileOutputStream fos = null;
		CipherOutputStream cos = null;

		try {
			fos = new FileOutputStream(file);

			SecretKeySpec localSecretKeySpec = new SecretKeySpec(App
					.createCompleteKey(imei).getBytes(), Encryptor.ALGO_AES);

			Cipher localCipher = Cipher.getInstance(Encryptor.ENC_AES);
			IvParameterSpec ivspec = new IvParameterSpec(App.IV.getBytes());
			localCipher.init(Cipher.ENCRYPT_MODE, localSecretKeySpec, ivspec);

			cos = new CipherOutputStream(fos, localCipher);

			cos.write(branchID.getBytes());
		} catch (Exception e) {
			if (e.getMessage() != null)
				throw e;
		} finally {
			try {
				if (cos != null)
					cos.close();
				if (fos != null)
					fos.close();
			} catch (Exception e2) {
				if (e2.getMessage() != null)
					throw e2;
			}
		}
	}
}
